package com.hex.ds.hdrs.label.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.hex.bigdata.hbda.base.Page;
import com.hex.ds.hdrs.app.po.AppConf;
import com.hex.ds.hdrs.app.service.impl.AppConfService;
import com.hex.ds.hdrs.common.enums.DataStatusEnum;
import com.hex.ds.hdrs.common.page.PageData;
import com.hex.ds.hdrs.label.converter.ILabelInfoConverter;
import com.hex.ds.hdrs.label.dao.LabelInfoDao;
import com.hex.ds.hdrs.label.dto.LabelInfoDto;
import com.hex.ds.hdrs.label.po.LabelInfoPo;
import com.hex.ds.hdrs.label.service.ILabelInfoService;
import com.hex.ds.hdrs.label.service.ILabelJobService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @Package: com.hex.ds.hdrs.label.service.impl
 * @ClassName LabelInfoServiceImpl
 * @Description: 标签业务实现类
 * @Author: ji.tang
 * @Date 2022/3/28 11:21
 * @Version v1.0
 **/
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class LabelInfoServiceImpl implements ILabelInfoService {

    private final LabelInfoDao labelInfoDao;

    private final ILabelJobService labelJobService;

    private final ILabelInfoConverter labelInfoConvert;

    private final AppConfService appConfService;

    /*
     * @Method: queryListByPage <br>
     * @Param: [labelInfoDto, page] <br>
     * @Return: com.hex.ds.hdrs.common.page.PageData <br>
     * @Description：分页查询<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/19 11:00 <br>
     * @Version： V2.0.2<br>
     */
    @Override
    public PageData queryListByPage(LabelInfoDto labelInfoDto, Page page) {
        LabelInfoPo labelInfoPo = labelInfoConvert.toLabelInfoPo(labelInfoDto);
        List<LabelInfoPo> labelInfoPoList = labelInfoDao.queryListByPage(labelInfoPo, page);
        for (LabelInfoPo labelInfo : labelInfoPoList) {
            if (StrUtil.isNotBlank(labelInfo.getAppCode())){
                AppConf appConf = appConfService.qryAppConfByAppCode(labelInfo.getAppCode());
                if (appConf != null){
                    labelInfo.setAppName(appConf.getAppName());
                }
            }
        }
        return new PageData(labelInfoPoList, page);
    }

    /**
     * @Method: qryLabelNameByJobCode <br>
     * @Param: [jobCode] <br>
     * @Return: java.util.List<java.lang.String> <br>
     * @Description：根据作业编码查询标签名称<br>
     * @Author： gc.zuo<br>
     * @Date： 2022/4/2 16:03 <br>
     * @Version： V1.0<br>
     */
    public List<LabelInfoPo> queryList(LabelInfoDto labelInfoDto) {
        LabelInfoPo labelInfoPo = labelInfoConvert.toLabelInfoPo(labelInfoDto);
        return labelInfoDao.queryList(labelInfoPo);
    }

    /*
     * @Method: queryListByJobCode <br>
     * @Param: [jobCode] <br>
     * @Return: java.util.List<com.hex.ds.hdrs.label.po.LabelInfoPo> <br>
     * @Description：根据作业编码查询对应的标签<br>
     * @Author： wz.li<br>
     * @Date： 2023/7/4 15:00 <br>
     * @Version： V2.0.2<br>
     */
    @Override
    public List<LabelInfoPo> queryListByJobCode(String jobCode) {
        LabelInfoDto labelInfoDto = new LabelInfoDto().setJobCode(jobCode);
        return queryList(labelInfoDto);
    }

    /*
     * @Method: queryById <br>
     * @Param: [pkId] <br>
     * @Return: com.hex.ds.hdrs.label.po.LabelInfoPo <br>
     * @Description：根据主键查询<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/19 10:54 <br>
     * @Version： V2.0.2<br>
     */
    @Override
    public LabelInfoPo queryById(String pkId) {
        return labelInfoDao.queryOne(new LabelInfoPo().setPkId(pkId));
    }

    /*
     * @Method: queryByLabelCode <br>
     * @Param: [labelCode] <br>
     * @Return: com.hex.ds.hdrs.label.po.LabelInfoPo <br>
     * @Description：根据标签编码查询<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/19 10:54 <br>
     * @Version： V2.0.2<br>
     */
    @Override
    public LabelInfoPo queryByLabelCode(String labelCode) {
        return labelInfoDao.queryOne(new LabelInfoPo().setLabelCode(labelCode));
    }

    /*
     * @Method: add <br>
     * @Param: [labelInfoDto] <br>
     * @Return: void <br>
     * @Description：新增标签<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/19 10:59 <br>
     * @Version： V2.0.2<br>
     */
    @Override
    public void add(LabelInfoDto labelInfoDto) {
        beforAdd(labelInfoDto);
        int count = labelInfoDao.insert(labelInfoConvert.toLabelInfoPoForAdd(labelInfoDto));
        if (count != 1) {
            throw new RuntimeException("新增标签失败！");
        }
    }

    /*
     * @Method: beforAdd <br>
     * @Param: [labelInfoDto] <br>
     * @Return: void <br>
     * @Description：标签新增前检查<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/19 10:59 <br>
     * @Version： V2.0.2<br>
     */
    private void beforAdd(LabelInfoDto labelInfoDto){
        LabelInfoPo labelInfoPo = queryByLabelCode(labelInfoDto.getLabelCode());
        if (labelInfoPo != null){
            throw new RuntimeException("标签编码已存在！");
        }
    }

    /*
     * @Method: modifyById <br>
     * @Param: [labelInfoDto] <br>
     * @Return: void <br>
     * @Description：修改标签<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/19 11:01 <br>
     * @Version： V2.0.2<br>
     */
    @Override
    public void modifyById(LabelInfoDto labelInfoDto) {
        beforModifyById(labelInfoDto);
        modifyById(labelInfoConvert.toLabelInfoPoForEdit(labelInfoDto));
    }

    /*
     * @Method: modifyById <br>
     * @Param: [labelInfoPo] <br>
     * @Return: void <br>
     * @Description：更新标签<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/19 11:03 <br>
     * @Version： V2.0.2<br>
     */
    private void modifyById(LabelInfoPo labelInfoPo){
        int count = labelInfoDao.modifyById(labelInfoPo);
        if (count != 1) {
            throw new RuntimeException("修改失败！");
        }
    }

    /*
     * @Method: beforModifyById <br>
     * @Param: [labelInfoDto] <br>
     * @Return: void <br>
     * @Description：更新前检查<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/19 11:01 <br>
     * @Version： V2.0.2<br>
     */
    private void beforModifyById(LabelInfoDto labelInfoDto){
        LabelInfoPo labelInfoPo = queryByLabelCode(labelInfoDto.getLabelCode());
        if (labelInfoPo != null && !labelInfoPo.getPkId().equals(labelInfoDto.getPkId())){
            throw new RuntimeException("标签编码已存在！");
        }
    }

    /*
     * @Method: batchRemoveById <br>
     * @Param: [pkIds] <br>
     * @Return: void <br>
     * @Description：根据主键批量删除<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/19 11:03 <br>
     * @Version： V2.0.2<br>
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void batchRemoveById(List<String> pkIds) {
        pkIds.stream().forEach((pkId) -> {
            removeById(pkId);
        });
    }

    /*
     * @Method: removeById <br>
     * @Param: [pkId] <br>
     * @Return: void <br>
     * @Description：根据主键删除标签<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/19 11:05 <br>
     * @Version： V2.0.2<br>
     */
    private void removeById(String pkId) {
        beforRemove(pkId);
        int count = labelInfoDao.removeById(pkId);
        if (count != 1) {
            throw new RuntimeException("删除失败！");
        }
    }

    /*
     * @Method: beforRemove <br>
     * @Param: [pkId] <br>
     * @Return: void <br>
     * @Description：删除前判断<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/19 11:17 <br>
     * @Version： V2.0.2<br>
     */
    private void beforRemove(String pkId){
        LabelInfoPo labelInfoPo = queryById(pkId);
        if (CollectionUtil.isNotEmpty(labelJobService.queryListByLabelCode(labelInfoPo.getLabelCode()))){
            throw new RuntimeException("该标签存在关联的作业，不允许删除");
        }
    }

    /*
     * @Method: batchEnableById <br>
     * @Param: [pkIds] <br>
     * @Return: void <br>
     * @Description：批量启用标签<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/19 11:18 <br>
     * @Version： V2.0.2<br>
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void batchEnableById(List<String> pkIds) {
        pkIds.stream().forEach((pkId) -> {
            LabelInfoPo labelInfoPo = queryById(pkId);
            labelInfoPo.setLabelStatus(DataStatusEnum.ENABLE.getName());
            modifyById(labelInfoPo);
        });
    }

    /*
     * @Method: batchDisableById <br>
     * @Param: [pkIds] <br>
     * @Return: void <br>
     * @Description：批量停用标签<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/19 11:19 <br>
     * @Version： V2.0.2<br>
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void batchDisableById(List<String> pkIds) {
        pkIds.stream().forEach((pkId) -> {
            LabelInfoPo labelInfoPo = queryById(pkId);
            labelInfoPo.setLabelStatus(DataStatusEnum.DISABLE.getName());
            modifyById(labelInfoPo);
        });
    }

    /*
     * @Method: checkLabelCode <br>
     * @Param: [labelInfoDto] <br>
     * @Return: boolean <br>
     * @Description：检查标签编码是否重复（平台必须唯一）<br>
     * @Author： wz.li<br>
     * @Date： 2023/7/12 11:47 <br>
     * @Version： V2.0.2<br>
     */
    @Override
    public boolean checkLabelCode(LabelInfoDto labelInfoDto) {
        LabelInfoPo labelInfoPo = queryByLabelCode(labelInfoDto.getLabelCode());
        return labelInfoPo != null && !labelInfoPo.getPkId().equals(labelInfoDto.getPkId());
    }

}
